<?php

namespace MoChat\App\NewHome\Action;

use EasyWeChat\Work\Application;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\DbConnection\Db;
use MoChat\App\Corp\Utils\WeWorkFactory;
use MoChat\App\WorkDepartment\Contract\WorkDepartmentContract;
use MoChat\Framework\Action\AbstractAction;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\RequestMapping;
use MoChat\App\Common\Middleware\DashboardAuthMiddleware;
use MoChat\App\Sales\Constants\SalesTaskStatusCode;
use MoChat\App\Sales\Contract\SalesClientTaskContract;
use MoChat\App\Sales\Contract\SalesClientTaskEmployeeContract;
use MoChat\App\Sales\Contract\SalesTaskContract;
use MoChat\Framework\Request\ValidateSceneTrait;
use MoChat\Framework\Exception\CommonException;
use MoChat\Framework\Constants\ErrorCode;
use MoChat\Plugin\Statistic\Logic\EmployeesLogic;

/**
 * 营销总览
 * @Controller
 */
class Index extends AbstractAction
{
    use ValidateSceneTrait;

    /**
     * @Inject
     * @var WorkDepartmentContract
     */
    protected $workDepartmentService;

    /**
     * @Inject
     * @var StdoutLoggerInterface
     */
    protected $logger;

    /**
     * @Inject
     * @var EmployeesLogic
     */
    protected $employeesLogic;
    /**
     * 根据微信企业ID获取easyWechat实例.
     *
     * @param int|string $corpId 微信corpid或企业表corpId
     */
    public function wxApp($corpId, string $type = 'user'): Application
    {
        $weWorkFactory = make(WeWorkFactory::class);
        if ($type === 'user') {
            return $weWorkFactory->getUserApp($corpId);
        }

        return $weWorkFactory->getContactApp($corpId);
    }
    private function wechatRecord($data,$user)
    {
        // 取出这个企业的所有成员
        $employeeList = $this->employeesLogic->getEmployees($user['corpIds'][0]);
        // 取出微信字母id
        $userIds = [];
        foreach ($employeeList as $item) {
            $userIds[] = $item['wxUserId'];
        }

        $result = [
            'chat_cnt' => 0,
        ];
        # #EasyWeChat获取「联系客户统计」数据
        $wx = $this->wxApp($user['corpIds'][0], 'contact')->external_contact_statistics;
        $start = 0;
        do {
            $wxUserId = array_slice($userIds, $start, 100);
            $start += 100;
            // 获取某些成员的某日期的统计数据
            $res = $wx->userBehavior($wxUserId, (string) strtotime($data['start_time']), (string) strtotime($data['end_time']));
            if ($res['errcode'] !== 0) {
                $this->logger->error(sprintf('获取「联系客户统计」数据 失败::[%s]', json_encode($res, JSON_THROW_ON_ERROR)));
            }
            $res = $res['behavior_data'];

            foreach ($res as $re) {
                $result['chat_cnt'] += @$re['chat_cnt'];
            }
        } while (count($wxUserId) === 100);
        return $result['chat_cnt'];
    }

    /**
     * @Middlewares({
     *     @Middleware(DashboardAuthMiddleware::class),
     * })
     * @RequestMapping(path="/dashboard/newHome/index", methods="GET")
     */
    public function handle()
    {
        $user = user();
        // 判断用户绑定企业信息
        if (!isset($user['corpIds']) || count($user['corpIds']) !== 1) {
            throw new CommonException(ErrorCode::INVALID_PARAMS, '未选择登录企业，不可操作');
        }
        $data = $this->request->all();
        $this->validated($data);
        $data = $this->typeEnum($data);
        $clientCount = $this->client($data['start_time'], $data['end_time']);
        $compareClientCount = $this->client($data['compare_start_time'], $data['compare_end_time']);
        $clientCountArray= $this->compute($clientCount, $compareClientCount);

        $callOutCount= $this->call($data['start_time'], $data['end_time']);
        $compareCallOutCount= $this->call($data['compare_start_time'], $data['compare_end_time']);
        $callOutCountArray= $this->compute($callOutCount, $compareCallOutCount);

        $clockCount=$this->clock($data['start_time'], $data['end_time']);
        $compareClockCount=$this->clock($data['compare_start_time'], $data['compare_end_time']);
        $clockCountArray= $this->compute($clockCount, $compareClockCount);

        $orderUserCount=$this->orderUser($data['start_time'], $data['end_time']);
        $compareOrderUserCount=$this->orderUser($data['compare_start_time'], $data['compare_end_time']);
        $orderUserCountArray= $this->compute($orderUserCount, $compareOrderUserCount);

        $orderTotalAmount=$this->userOrderMoney($data['start_time'], $data['end_time']);
        $compareOrderTotalAmount=$this->userOrderMoney($data['compare_start_time'], $data['compare_end_time']);
        $orderTotalAmountCountArray= $this->compute($orderTotalAmount, $compareOrderTotalAmount);


        $wechatCount = $this->wechatRecord($data, $user);
        $compareWechatCount = $this->wechatRecord(['start_time'=>$data['compare_start_time'],'end_time'=> $data['compare_end_time']],$user);
        $wechatCountArray= $this->compute($wechatCount, $compareWechatCount);

        return [
            'client' => [
                'count' => $clientCountArray['count'],//总客户数
                'type' => $clientCountArray['type'],//1上升,2下降
                'rate' => $clientCountArray['rate'],
            ],
            'call' => [
                'count' => $callOutCountArray['count'],//呼出通话数
                'type' => $callOutCountArray['type'],//1上升,2下降
                'rate' => $callOutCountArray['rate'],
            ],
            'clock' => [
                'count' => $clockCountArray['count'],//外勤打卡数量
                'type' => $clockCountArray['type'],//1上升,2下降
                'rate' => $clockCountArray['rate'],
            ],
            'wechat' => [
                'count' => $wechatCountArray['count'],//企微沟通数
                'type' => $wechatCountArray['type'],//1上升,2下降
                'rate' => $wechatCountArray['rate'],
            ],
            'orderUser' => [
                'count' => $orderUserCountArray['count'],//下单客户数
                'type' => $orderUserCountArray['type'],//1上升,2下降
                'rate' => $orderUserCountArray['rate'],
            ],
            'orderTotalAmount' => [
                'count' => $orderTotalAmountCountArray['count'],//下单总金额
                'type' => $orderTotalAmountCountArray['type'],//1上升,2下降
                'rate' => $orderTotalAmountCountArray['rate'],
            ],
        ];
    }

    /**
     * 总客户数
     * @param $startTime
     * @param $endTime
     * @return int
     */
    private function client($startTime, $endTime): int
    {
        return Db::table('client')
           ->count();
//        return Db::table('client')
//            ->where('created_at', '>=', $startTime)
//            ->where('created_at', '<', $endTime)
//            ->count();
    }

    /**
     * 呼出电话
     * @param $startTime
     * @param $endTime
     * @return int
     */
    private function call($startTime, $endTime): int
    {
       return Db::table('call_record')
            ->where('created_time', '>=',$startTime)
            ->where('created_time', '<',$endTime)
            ->where('call_type', '=', 'out')
            ->count();
    }

    /**
     * 外勤打卡数量
     * @param $startTime
     * @param $endTime
     * @return int
     */
    private function clock($startTime, $endTime): int
    {
       return Db::table('clock_record')
            ->where('created_at', '>=', $startTime)
            ->where('created_at', '<', $endTime)
            ->count();
    }

    /**
     * 用户订单数
     * @param $startTime
     * @param $endTime
     * @return int
     */
    private function orderUser($startTime, $endTime): int
    {
        return Db::connection('b2b')->table('user_order as order')
            ->join('order_status as status','status.ID','=','order.ID')
            ->where('status.STATUS_', '>=', 0)
            ->whereBetween('order.CREATE_TIME',[$startTime, $endTime])
            ->count();
    }

    /**
     * 订单金额
     * @param $startTime
     * @param $endTime
     * @return int|mixed|string
     */
    private function userOrderMoney($startTime, $endTime)
    {
        return Db::connection('b2b')->table('user_order as order')
            ->join('order_status as status','status.ID','=','order.ID')
            ->where('status.STATUS_', '>=', 0)
            ->whereBetween('order.CREATE_TIME',[$startTime, $endTime])
            ->sum('TOTAL_AMOUNT');
    }
    /**
     * 计算
     * @param $now
     * @param $before
     * @return array
     */
    private function compute($now, $before): array
    {
        //现在大于之前
        if ($now > $before) {
            $diff = bcsub((string)$now, (string)$before, 2);
            $rate = $before ? bcdiv($diff, $before, 2) : 1;
            return [
                'count'=>$now,
                'type' => 1,
                'rate' => bcmul($rate, 100, 2) . '%'
            ];
        }

        //现在小于或者等于之前
        $diff = bcsub((string)$before, (string)$now, 2);
        $rate = $before?bcdiv($diff, $before, 2):1;
        return [
            'count'=>$now,
            'type' => 2,
            'rate' => bcmul($rate, 100, 2) . '%'
        ];
    }

    private function typeEnum($data)
    {
        //默认
        $timeRange = [
            'start_time' => date('Y-m-d 00:00:00'),
            'end_time' => date('Y-m-d H:i:s'),
            'compare_start_time' => date('Y-m-d 00:00:00', strtotime('-1 day')),
            'compare_end_time' => date('Y-m-d 00:00:00'),
        ];
        //今日
        if ($data['type'] == 1) {
            $timeRange = [
                'start_time' => date('Y-m-d 00:00:00'),
                'end_time' => date('Y-m-d H:i:s'),
                'compare_start_time' => date('Y-m-d 00:00:00', strtotime('-1 day')),
                'compare_end_time' => date('Y-m-d 00:00:00'),
            ];
        }
        //昨日
        if ($data['type'] == 2) {
            $timeRange = [
                'start_time' => date('Y-m-d 00:00:00', strtotime('-1 day')),
                'end_time' => date('Y-m-d 00:00:00'),
                'compare_start_time' => date('Y-m-d 00:00:00', strtotime('-2 day')),
                'compare_end_time' => date('Y-m-d 00:00:00', strtotime('-1 day')),
            ];
        }
        //本月
        if ($data['type'] == 3) {
            $timeRange = [
                'start_time' => date('Y-m-01 00:00:00'),
                'end_time' => date('Y-m-d H:i:s'),
                'compare_start_time' => date('Y-m-01 00:00:00', strtotime('-1 month')),
                'compare_end_time' => date('Y-m-01 00:00:00'),
            ];
        }
        //上月
        if ($data['type'] == 4) {
            $start = date('Y-m-01 00:00:00', strtotime('-1 month'));
            $timeRange = [
                'start_time' => date('Y-m-01 00:00:00', strtotime('-1 month')),
                'end_time' => date('Y-m-d H:i:s', strtotime('+1 month', strtotime($start))),
                'compare_start_time' => date('Y-m-01 00:00:00', strtotime('-2 month')),
                'compare_end_time' => date('Y-m-01 00:00:00', strtotime('-1 month')),
            ];
        }
        //默认
        return array_merge($data, $timeRange);
    }


    /**
     * 验证规则.
     */
    protected function rules(): array
    {
        return [
            'type' => 'in:1,2,3,4',
        ];
    }

    /**
     * 获取已定义验证规则的错误消息.
     */
    protected function messages(): array
    {
        return [
            'type.in' => 'type参数错误',
        ];
    }
}
